home *** CD-ROM | disk | FTP | other *** search
/ Programming an RTS Game with Direct3D / Programming an RTS Game with Direct3D.iso / Examples / Chapter 9 / Example 9.3 / app.cpp next >
Encoding:
C/C++ Source or Header  |  2006-08-01  |  8.2 KB  |  329 lines

  1. //////////////////////////////////////////////////////////////
  2. // Example 9.3: Player Example                                //
  3. // Written by: C. Granberg, 2006                            //
  4. //////////////////////////////////////////////////////////////
  5.  
  6. #include <windows.h>
  7. #include <d3dx9.h>
  8. #include "debug.h"
  9. #include "shader.h"
  10. #include "terrain.h"
  11. #include "camera.h"
  12. #include "mouse.h"
  13. #include "player.h"
  14.  
  15. class APPLICATION
  16. {
  17.     public:
  18.         APPLICATION();
  19.         HRESULT Init(HINSTANCE hInstance, int width, int height, bool windowed);
  20.         HRESULT Update(float deltaTime);
  21.         HRESULT Render();
  22.         HRESULT Cleanup();
  23.         HRESULT Quit();
  24.         DWORD FtoDword(float f){return *((DWORD*)&f);}
  25.  
  26.         void AddPlayers(int noPlayers);
  27.  
  28.     private:
  29.         IDirect3DDevice9* m_pDevice; 
  30.         TERRAIN m_terrain;
  31.         CAMERA m_camera;
  32.         MOUSE m_mouse;
  33.         std::vector<PLAYER*> m_players;
  34.  
  35.         bool m_wireFrame;
  36.         DWORD m_time;
  37.         int m_fps, m_lastFps;
  38.         HWND m_mainWindow;
  39.         ID3DXFont *m_pFont;
  40. };
  41.  
  42. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd)
  43. {
  44.     APPLICATION app;
  45.  
  46.     if(FAILED(app.Init(hInstance, 800, 600, true)))
  47.         return 0;
  48.  
  49.     MSG msg;
  50.     memset(&msg, 0, sizeof(MSG));
  51.     int startTime = timeGetTime(); 
  52.  
  53.     while(msg.message != WM_QUIT)
  54.     {
  55.         if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
  56.         {
  57.             ::TranslateMessage(&msg);
  58.             ::DispatchMessage(&msg);
  59.         }
  60.         else
  61.         {    
  62.             int t = timeGetTime();
  63.             float deltaTime = (t - startTime)*0.001f;
  64.  
  65.             app.Update(deltaTime);
  66.             app.Render();
  67.  
  68.             startTime = t;
  69.         }
  70.     }
  71.  
  72.     app.Cleanup();
  73.  
  74.     return msg.wParam;
  75. }
  76.  
  77. APPLICATION::APPLICATION()
  78. {
  79.     m_pDevice = NULL; 
  80.     m_mainWindow = 0;
  81.     m_wireFrame = false;
  82.     srand(GetTickCount());
  83.     m_fps = m_lastFps = 0;
  84.     m_time = GetTickCount();
  85. }
  86.  
  87. HRESULT APPLICATION::Init(HINSTANCE hInstance, int width, int height, bool windowed)
  88. {
  89.     debug.Print("Application initiated");
  90.  
  91.     //Create Window Class
  92.     WNDCLASS wc;
  93.     memset(&wc, 0, sizeof(WNDCLASS));
  94.     wc.style         = CS_HREDRAW | CS_VREDRAW;
  95.     wc.lpfnWndProc   = (WNDPROC)::DefWindowProc; 
  96.     wc.hInstance     = hInstance;
  97.     wc.lpszClassName = "D3DWND";
  98.  
  99.     //Register Class and Create new Window
  100.     RegisterClass(&wc);
  101.     m_mainWindow = CreateWindow("D3DWND", "Example 9.3: Player Example", WS_EX_TOPMOST, 0, 0, width, height, 0, 0, hInstance, 0); 
  102.     SetCursor(NULL);
  103.     ShowWindow(m_mainWindow, SW_SHOW);
  104.     UpdateWindow(m_mainWindow);
  105.  
  106.     //Create IDirect3D9 Interface
  107.     IDirect3D9* d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
  108.  
  109.     if(d3d9 == NULL)
  110.     {
  111.         debug.Print("Direct3DCreate9() - FAILED");
  112.         return E_FAIL;
  113.     }
  114.  
  115.     //Check that the Device supports what we need from it
  116.     D3DCAPS9 caps;
  117.     d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);
  118.  
  119.     //Hardware Vertex Processing or not?
  120.     int vp = 0;
  121.     if(caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
  122.         vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
  123.     else vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
  124.  
  125.     //Check vertex & pixelshader versions
  126.     if(caps.VertexShaderVersion < D3DVS_VERSION(2, 0) || caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
  127.     {
  128.         debug.Print("Warning - Your graphic card does not support vertex and pixelshaders version 2.0");
  129.     }
  130.  
  131.     //Set D3DPRESENT_PARAMETERS
  132.     D3DPRESENT_PARAMETERS d3dpp;
  133.     d3dpp.BackBufferWidth            = width;
  134.     d3dpp.BackBufferHeight           = height;
  135.     d3dpp.BackBufferFormat           = D3DFMT_A8R8G8B8;
  136.     d3dpp.BackBufferCount            = 1;
  137.     d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE;
  138.     d3dpp.MultiSampleQuality         = 0;
  139.     d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD; 
  140.     d3dpp.hDeviceWindow              = m_mainWindow;
  141.     d3dpp.Windowed                   = windowed;
  142.     d3dpp.EnableAutoDepthStencil     = true; 
  143.     d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;
  144.     d3dpp.Flags                      = 0;
  145.     d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
  146.     d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;
  147.  
  148.     //Create the IDirect3DDevice9
  149.     if(FAILED(d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_mainWindow,
  150.                                  vp, &d3dpp, &m_pDevice)))
  151.     {
  152.         debug.Print("Failed to create IDirect3DDevice9");
  153.         return E_FAIL;
  154.     }
  155.  
  156.     //Release IDirect3D9 interface
  157.     d3d9->Release();
  158.  
  159.     D3DXCreateFont(m_pDevice, 18, 0, 0, 1, false,  
  160.                    DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY,
  161.                    DEFAULT_PITCH | FF_DONTCARE, "Arial", &m_pFont);
  162.  
  163.     LoadObjectResources(m_pDevice);
  164.     LoadMapObjectResources(m_pDevice);
  165.     LoadUnitResources(m_pDevice);
  166.     LoadBuildingResources(m_pDevice);
  167.     LoadPlayerResources(m_pDevice);
  168.  
  169.     m_terrain.Init(m_pDevice, INTPOINT(150,150));
  170.  
  171.     m_mouse.InitMouse(m_pDevice, m_mainWindow);
  172.  
  173.     m_camera.Init(m_pDevice);
  174.     m_camera.m_fov = 0.6f;
  175.     m_camera.m_radius = 50.0f;
  176.  
  177.     //Set sampler state
  178.     for(int i=0;i<8;i++)
  179.     {
  180.         m_pDevice->SetSamplerState(i, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
  181.         m_pDevice->SetSamplerState(i, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
  182.         m_pDevice->SetSamplerState(i, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
  183.     }
  184.  
  185.     AddPlayers(4);
  186.     
  187.     return S_OK;
  188. }
  189.  
  190. HRESULT APPLICATION::Update(float deltaTime)
  191. {        
  192.     //Control camera
  193.     m_camera.Update(m_mouse, m_terrain, deltaTime);
  194.     m_mouse.Update(m_terrain);
  195.  
  196.     //Update Players
  197.     for(int i=0;i<m_players.size();i++)
  198.         if(m_players[i] != NULL)
  199.             m_players[i]->UpdateMapObjects(deltaTime);
  200.  
  201.     //Order units of team 0 around...
  202.     if(m_players.size() > 0 && m_players[0] != NULL)
  203.         m_players[0]->UnitOrders(m_mouse);
  204.  
  205.     //Keyboard input
  206.     if(KEYDOWN('W'))
  207.     {
  208.         m_wireFrame = !m_wireFrame;
  209.         Sleep(300);
  210.     }
  211.     else if(KEYDOWN(VK_SPACE))
  212.     {
  213.         m_terrain.GenerateRandomTerrain(9);
  214.         AddPlayers(4);
  215.     }
  216.     else if(KEYDOWN(VK_ESCAPE))
  217.     {
  218.         Quit();
  219.     }
  220.  
  221.     return S_OK;
  222. }    
  223.  
  224. HRESULT APPLICATION::Render()
  225. {
  226.     // Clear the viewport
  227.     m_pDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
  228.  
  229.     //FPS Calculation
  230.     m_fps++;
  231.     if(GetTickCount() - m_time > 1000)
  232.     {
  233.         m_lastFps = m_fps;
  234.         m_fps = 0;
  235.         m_time = GetTickCount();
  236.     }
  237.  
  238.     // Begin the scene 
  239.     if(SUCCEEDED(m_pDevice->BeginScene()))
  240.     {
  241.         if(m_wireFrame)m_pDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);    
  242.         else m_pDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
  243.  
  244.         m_terrain.Render(m_camera);
  245.  
  246.         for(int i=0;i<m_players.size();i++)
  247.             if(m_players[i] != NULL)
  248.                 m_players[i]->RenderMapObjects(m_camera);
  249.  
  250.         //Select units
  251.         if(m_players.size() > 0 && m_players[0] != NULL)
  252.         {
  253.             m_players[0]->PaintSelectedMapObjects(m_camera);
  254.             m_players[0]->Select(m_mouse);
  255.         }
  256.         m_mouse.Paint();
  257.  
  258.         //FPS
  259.         char number[50];
  260.         std::string text = "FPS: ";
  261.         text += _itoa(m_lastFps, number, 10);
  262.         RECT rc = {720, 10, 0, 0};
  263.         m_pFont->DrawText(NULL, text.c_str(), -1, &rc, DT_LEFT| DT_TOP | DT_NOCLIP, 0xff000000);
  264.  
  265.         // End the scene.
  266.         m_pDevice->EndScene();
  267.         m_pDevice->Present(0, 0, 0, 0);
  268.     }
  269.  
  270.     return S_OK;
  271. }
  272.  
  273. HRESULT APPLICATION::Cleanup()
  274. {
  275.     try
  276.     {
  277.         m_terrain.Release();
  278.  
  279.         UnloadObjectResources();
  280.         UnloadMapObjectResources();
  281.         UnloadUnitResources();
  282.         UnloadBuildingResources();
  283.         UnloadPlayerResources();
  284.  
  285.         for(int i=0;i<m_players.size();i++)
  286.             if(m_players[i] != NULL)
  287.                 delete m_players[i];
  288.         m_players.clear();
  289.  
  290.         m_pFont->Release();
  291.         m_pDevice->Release();
  292.  
  293.         debug.Print("Application terminated");
  294.     }
  295.     catch(...){}
  296.  
  297.     return S_OK;
  298. }
  299.  
  300. HRESULT APPLICATION::Quit()
  301. {
  302.     ::DestroyWindow(m_mainWindow);
  303.     ::PostQuitMessage(0);
  304.     return S_OK;
  305. }
  306.  
  307. void APPLICATION::AddPlayers(int noPlayers)
  308. {
  309.     for(int i=0;i<m_players.size();i++)
  310.         if(m_players[i] != NULL)
  311.             delete m_players[i];
  312.     m_players.clear();
  313.  
  314.     INTPOINT startLocations[] = {INTPOINT(30,30), INTPOINT(120,30), INTPOINT(30,120), INTPOINT(120,120)};
  315.     D3DXVECTOR4 teamCols[] = {D3DXVECTOR4(1.0f, 0.0f, 0.0f, 1.0f), D3DXVECTOR4(0.0f, 1.0f, 0.0f, 1.0f),
  316.                               D3DXVECTOR4(0.0f, 0.0f, 1.0f, 1.0f), D3DXVECTOR4(1.0f, 1.0f, 0.0f, 1.0f)};
  317.     
  318.     if(noPlayers < 2)noPlayers = 2;
  319.     if(noPlayers > 4)noPlayers = 4;
  320.  
  321.     for(int i=0;i<noPlayers;i++)
  322.     {
  323.         m_terrain.Progress("Creating Players", i / (float)noPlayers);
  324.         m_players.push_back(new PLAYER(i, teamCols[i], startLocations[i], &m_terrain, m_pDevice));    
  325.     }
  326.  
  327.     //Center camera focus on the team...
  328.     m_camera.m_focus = m_terrain.GetWorldPos(m_players[0]->GetCenter());
  329. }